package com.yuanmeng.common.core.thread;

import java.util.concurrent.*;

import com.google.common.util.concurrent.ThreadFactoryBuilder;


/**
 * 线程池
 * @author outsider
 * @version Id: ThreadPoolManager.java, v 0.1 2020/12/17 19:18 outsider Exp $$
 */
public class ThreadPoolManager {
    private static final LogHelper logger = LogHelper.getInstance("ThreadPoolManager");

    private ThreadPoolManager() {

    }

    /**
     * 设置核心池大小
     */
    private static int                            corePoolSize         = 30;
    /**
     * 最大线程数
     */
    private static final int                      MAXIMUM_POOL_SIZE    = 30;
    /**
     * 设置线程池最大能接受多少线程
     */
    private static int                            maxPoolSize          = 100;

    /**
     * 当前线程数大于corePoolSize、小于maximumPoolSize时，超出corePoolSize的线程数的生命周期
     */
    private static long                           keepAliveTime        = 300L;

    /**
     * 队列容量
     */
    private static int                            capacity             = 1000;

    /**
     * 设置时间单位，秒
     */
    private static TimeUnit                       timeUnit             = TimeUnit.SECONDS;

    /**
     * 排队策略 放入队列
     */
    private static LinkedBlockingDeque<Runnable>  linkedBlockingDeque  = new LinkedBlockingDeque<>(
        capacity);

    /**
     * 线程池的策略模式
     */
    private static final RejectedExecutionHandler REJ_HANDLER          = new ThreadPoolExecutor.CallerRunsPolicy();

    /**
     * 定义线程池的名称
     */
    public static final ThreadFactory             NAMED_THREAD_FACTORY = new ThreadFactoryBuilder()
        .setNameFormat("dream-linwan").build();
    /**
     * 创建线程池
     */
    public static final ExecutorService THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            timeUnit,
            linkedBlockingDeque,
            NAMED_THREAD_FACTORY,
            (r, e) -> {
                logger.info("dream-linwan");
                if (!e.isShutdown()) {
                    e.getQueue().poll();
                    e.execute(r);
                }
            });

    private static ThreadPoolExecutor             threadPoolExecutor   = null;

    public synchronized static ThreadPoolExecutor getInstance() {
        if (threadPoolExecutor == null) {
            threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, MAXIMUM_POOL_SIZE,
                keepAliveTime, timeUnit, new LinkedBlockingQueue<>(),
                new BusinessThreadFactory("dream-linwan"), REJ_HANDLER);
        }
        return threadPoolExecutor;
    }
}
